package com.zebra.json;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.ReflectUtil;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;

import java.math.BigDecimal;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 *
 * @Description: TODO 这种不同的类型使用不同的序列化策略
 *          1.当序列化类型为数组集合时，当值为null时，序列化成[]
 *          2.字符串类型值序列化为""
 *          3.数字类型设默认值 0
 *          4.布尔类型设置false
 * @auther: litaolin
 * @date: 09:06:23 2020-05-28 
 * @param: 
 * @return: 
 *
 */
public class JacksonBeanSerializerModifier extends BeanSerializerModifier {

    @Override
    public List<BeanPropertyWriter> changeProperties(SerializationConfig config,
                                                     BeanDescription beanDesc,
                                                     List<BeanPropertyWriter> beanProperties) {
        // 循环所有的beanPropertyWriter
        for (int i = 0; i < beanProperties.size(); i++) {
            BeanPropertyWriter writer = beanProperties.get(i);
            if (isArrayType(writer)) {
                writer.assignNullSerializer(new JacksonNullJsonSerializer.NullArrayJsonSerializer());
            }
            if (isStringType(writer)) {
                writer.assignNullSerializer(new JacksonNullJsonSerializer.NullStringJsonSerializer());
            }
            if (isBooleanType(writer)) {
                writer.assignNullSerializer(new JacksonNullJsonSerializer.NullBooleanJsonSerializer());
            }
            if (isNumberType(writer)) {
                writer.assignNullSerializer(new JacksonNullJsonSerializer.NullNumberJsonSerializer());
            }
            if(isDateType(writer)){
                writer.assignNullSerializer(new JacksonNullJsonSerializer.NullStringJsonSerializer());
            }
        }
        return beanProperties;
    }

    private boolean isDateType(BeanPropertyWriter writer) {
        Class<?> clazz = writer.getType().getRawClass();
        return Date.class.isAssignableFrom(clazz)
                || java.sql.Date.class.isAssignableFrom(clazz)
                || Timestamp.class.isAssignableFrom(clazz)
                || DateTime.class.isAssignableFrom(clazz)
                || Time.class.isAssignableFrom(clazz);
    }


    /**
     * 判断是否为数组
     * @param writer
     * @return
     */
    private boolean isArrayType(BeanPropertyWriter writer) {
        Class<?> clazz = writer.getType().getRawClass();
        return clazz.isArray()
               || Collection.class.isAssignableFrom(clazz)
               || Map.class.isAssignableFrom(clazz);
    }

    /**
     * 判断是否为字符串
     */
    private boolean isStringType(BeanPropertyWriter writer) {
        Class<?> clazz = writer.getType().getRawClass();
        return CharSequence.class.isAssignableFrom(clazz) || Character.class.isAssignableFrom(clazz);
    }

    /**
     * 是否是数值类型
     */
    private boolean isNumberType(BeanPropertyWriter writer) {
        Class<?> clazz = writer.getType().getRawClass();
        return Number.class.isAssignableFrom(clazz);
    }


    /**
     * 是否是boolean
     */
    private boolean isBooleanType(BeanPropertyWriter writer) {
        Class<?> clazz = writer.getType().getRawClass();
        return clazz.equals(Boolean.class);
    }

}
